PHPUnit是PHP中最早也是最成熟的單元測試框架。除了可以使用他來做單元測試,他還可以擴充,並且驅動許多種不同的測試。包含針對Database做測試、透過Selemium做整合測試、透過Mock與Stub模擬Context、支援TDD及BDD、透過Class產生單元測試程式骨架或透過單元測試程式產生類別、計算測試覆蓋率、並且與不同的ticket系統互動。
這些功能單靠幾次嘗試大概無法都顧及,所以還是先從重要的開始嘗試。今天先簡單看一下怎麼安裝,怎麼寫測試,以及怎麼看測試結果。
參考:
* https://github.com/sebastianbergmann/phpunit/
* http://phpunit.de/manual/current/en/index.html
* 安裝PHPUnit
首先來看一下怎樣安裝。
早期安裝PHPUnit大概都是透過PEAR,不過3.7.5版開始,PHPUnit也可以透過Composer來安裝。參考之前的Composer設定方法,只要設定:
{
"require": {
"phpunit/phpunit": "~3.7.5"
}
}
然後執行composer install就可以。
Feng-Hsu-Pingteki-MacBook-Air:2-2a fillano$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
file_put_contents(/Users/fillano/.composer/cache/repo/https---packagist.org/provider-symfony$yaml.json): failed to open stream: Permission denied
http://packagist.org could not be fully loaded, package information was loaded from the local cache and may be out of date
- Installing symfony/yaml (v2.3.4)
Loading from cache
- Installing phpunit/php-text-template (1.1.4)
Downloading: 100%
- Installing phpunit/phpunit-mock-objects (1.2.3)
Downloading: 100%
- Installing phpunit/php-timer (1.0.5)
Loading from cache
- Installing phpunit/php-token-stream (1.2.1)
Downloading: 100%
- Installing phpunit/php-file-iterator (1.3.3)
Downloading: 100%
- Installing phpunit/php-code-coverage (1.2.13)
Downloading: 100%
- Installing phpunit/phpunit (3.7.27)
Downloading: 100%
phpunit/php-code-coverage suggests installing ext-xdebug (>=2.0.5)
phpunit/phpunit suggests installing phpunit/php-invoker (>=1.1.0,<1.2.0)
Writing lock file
Generating autoload files
不過安裝完畢後,會看到兩個提示,建議同時安裝php的延伸模組xdebug與phpunit/php-invoker套件。所以需要再調整一下設定。另外,安裝phpunit的目的是在開發期間做測試,並不是發佈時需要。這方面依賴的套件,其實設定時比較適合擺在require-dev而不是require。所以先刪掉composer.lock檔案,修改一下composer.json:
{
"require":{
},
"require-dev": {
"phpunit/phpunit":"~3.7.5",
"phpunit/php-invoker":"~1.1.0"
}
}
由於我使用了phpbrew,可以透過他直接安裝extension,所以先執行一下phpbrew來安裝xdebug:
Feng-Hsu-Pingteki-MacBook-Air:2-2a fillano$ phpbrew switch php-5.4.20
Feng-Hsu-Pingteki-MacBook-Air:2-2a fillano$ phpbrew ext install xdebug
...
如果沒有使用phpbrew的話,可以上:http://xdebug.org/download.php找一下下載的檔案,我就不仔細介紹。之後應該還會嘗試使用xdebug來做profiling,到時再仔細看一下不同平台的安裝方式。
安裝完畢後,再執行一次composer install,這時composer會警告,php-invoker需要ext-pcntl才能執行,所以再用phpbrew安裝一下...(phpbrew ext install pcntl),然後執行composer install...
Feng-Hsu-Pingteki-MacBook-Air:2-2a fillano$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
file_put_contents(/Users/fillano/.composer/cache/repo/https---packagist.org/provider-symfony$yaml.json): failed to open stream: Permission denied
http://packagist.org could not be fully loaded, package information was loaded from the local cache and may be out of date
- Installing symfony/yaml (v2.3.4)
Loading from cache
- Installing phpunit/php-text-template (1.1.4)
Loading from cache
- Installing phpunit/phpunit-mock-objects (1.2.3)
Loading from cache
- Installing phpunit/php-timer (1.0.5)
Loading from cache
- Installing phpunit/php-token-stream (1.2.1)
Loading from cache
- Installing phpunit/php-file-iterator (1.3.4)
Loading from cache
- Installing phpunit/php-code-coverage (1.2.13)
Loading from cache
- Installing phpunit/phpunit (3.7.27)
Loading from cache
- Installing phpunit/php-invoker (1.1.3)
Loading from cache
phpunit/phpunit-mock-objects suggests installing ext-soap (*)
Writing lock file
Generating autoload files
結果他又建議要安裝ext-soap這個擴充模組,所以再次動用phpbrew:
Feng-Hsu-Pingteki-MacBook-Air:2-2a fillano$ phpbrew ext install soap
===> Installing soap extension...
===> Phpizing...
===> Configuring...
===> Building...
===> Installing...
===> Extension is installed.
===> Enabling extension
Done
這樣應該就差不多了。(不過其實phpbrew執行安裝的方式不太對,最好用`phpbrew install php-5.x.x +default +pcntl +xml +soap`先把php module裝好,然後執行`phpbrew ext install xdebug`來安裝xdebug。)
安裝完畢後...還有一個問題...就是,phpunit除了是程式庫,同時也是命令列工具,需要用它來執行測試。所以需要額外讓他可以被執行...可以用composer將phpunit安裝成global的套件:
接下來,就可以些一些簡單的單元測試案例。先寫一個簡單的類別:ShowName:
<?php
class ShowName
{
private $name = '';
public function __construct($name)
{
$this->name = $name;
}
public function show()
{
return $this->name;
}
}
然後針對show方法寫一個簡單的單元測試:
<?php
require 'vendor/autoload.php';
require 'ShowName.php';
class ShowNameTest extends PHPUnit_Framework_TestCase
{
public function testShow()
{
$name = 'fillano';
$target = new ShowName($name);
$this->assertEquals($target->show(), $name);
}
}
然後執行:
Feng-Hsu-Pingteki-MacBook-Air:2-2a fillano$ phpunit ShowNameTest
PHPUnit 3.7.27 by Sebastian Bergmann.
.
Time: 67 ms, Memory: 2.75Mb
OK (1 test, 1 assertion)
這樣就表示順利執行,並且通過測試。上面的"."代表執行測試的數目,也就是執行TestCase類別中的測試方法的數目。顯示OK時,表示測試通過,後面的資訊會提示執行了幾個測試及assertion。phpunit提供了很多的assertion方法,最常使用的大概就是assertEquals(),用來確定執行的結果是否符合預期(執行的結果與某個值是否符合),不符的話測試就會失敗。
今天就先到這裡吧,之後再詳細介紹一下單元測試與phpunit可以驅動的其他測試。